﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using SMBL.Interface.Document;

namespace SMBL.AFS
{
    /// <summary>
    /// Document Pool
    /// This class is used to control all files.
    /// @Author: Push
    /// </summary>
    public class DocumentPool : SMBL.Interface.AbstractServer.IAS
    {
        /// <summary>
        /// The main document pool
        /// </summary>
        private static Hashtable myMainDocPool;

        /// <summary>
        /// The private document pool as abstract system.
        /// </summary>
        private static DocumentPool myDP;

        /// <summary>
        /// Unreachable construction.
        /// For singleton usage.
        /// </summary>
        private DocumentPool(){}

        public static SMBL.Interface.AbstractServer.IAS SingletonInstance()
        {
            if (myDP == null) myDP = new DocumentPool();
            return myDP;
        }

        /// <summary>
        /// Format the file path to the unite style
        /// @Author: Push
        /// </summary>
        /// <param name="FilePath"></param>
        /// <returns></returns>
        private static String formatFilePath(String FilePath)
        {
            if (FilePath.StartsWith(Global.WebSite.AppPath))
                return FilePath.Substring(Global.WebSite.AppPath.Length);
            if (FilePath.StartsWith("\\") || FilePath.StartsWith("/"))
                return FilePath.Substring(1);
            return FilePath;
        }

        #region IAS Members

        public SMBL.Interface.AbstractServer.IAProvider GetProvider(string BindString)
        {
            //throw new NotImplementedException();
            // Format the file path
            String tmpPath = formatFilePath(BindString);

            // Check the pool if the file has been in.
            // If not, add it.
            if (!myMainDocPool.ContainsKey(tmpPath))
            {
                myMainDocPool.Add(tmpPath, false);
            }

            // Lock the document
            //Providers.Document _rtn = new Providers.Document(tmpPath);
            while ((Boolean)myMainDocPool[tmpPath]) ;
            myMainDocPool[tmpPath] = true;

            // Return the provider
            return new Providers.Document(tmpPath);
        }

        public bool ReleaseProvider(string BindString, ref SMBL.Interface.AbstractServer.IAProvider theProvider)
        {
            //throw new NotImplementedException();
            Providers.Document tmpDoc = (Providers.Document)theProvider;
            theProvider.End();
            myMainDocPool[tmpDoc.FormatedFilePath] = false;
            return true;
        }

        private bool _isStarted = false;
        public bool IsStarted
        {
            //throw new NotImplementedException();
            get { return _isStarted; }
        }

        private bool _beLocked = false;
        public bool IsAvailable
        {
            //throw new NotImplementedException();
            get { return _beLocked; }
        }

        #endregion

        #region IStart Members

        public bool Start()
        {
            //throw new NotImplementedException();
            myMainDocPool = new Hashtable();
            this._isStarted = true;
            return true;
        }

        #endregion

        #region IRestart Members

        public bool Restart()
        {
            //throw new NotImplementedException();
            this._beLocked = true;
            this.End();
            this.Start();
            this._beLocked = false;
            return true;
        }

        #endregion

        #region IEnd Members

        public bool End()
        {
            //throw new NotImplementedException();
            myMainDocPool.Clear();
            this._isStarted = false;
            return true;
        }

        #endregion
    }
}
